<!DOCTYPE html>
<html lang="zh-CN">

<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>
</head>

<body>
   <p class="one"></p>
   <button class="two" onclick="this.style.display='none', fun(), console.log(this)">这是一个按钮</button>
   <p class="three"></p>
   <script>
      //JavaScript 中 this 不是固定不变的，它会随着执行环境的改变而改变
      let x = this;
      console.log(this);
      // 在变量中的this 指向它的顶级对象 window

      function fn(a) {
         console.log(this);
      }
      fn(1)
      //在普通函数中,this指向它的顶级对象window

      let person = {
         a: '今天天气真好',
         b: '咱们出去散步吧',
         c: function () {
            let p = [this.a + " " + this.b, console.log(this)]
            return p
         }
      }
      document.querySelector('.one').innerHTML = person.c()
      // 在方法中this 指向的它所在的方法也就是person

      function fun() {
         // document.querySelector(".two")
         alert("这是一个弹出框")
         console.log(this);
      }
      // 这里的this指向window对象 ; 但是在button事件中的this指向接受事件的HTML标签本身(button按钮本身)

      var person1 = {
         fullName: function () {
            return this.firstName + " " + this.lastName;
         }
      }
      var person2 = {
         firstName: "John",
         lastName: "Doe",
      }
      document.querySelector(".three").innerHTML = (person1.fullName.call(person2)) //将输出 John Doe
      // 显式函数绑定在 JavaScript 中函数也是对象，对象则有方法，apply 和 call 就是函数对象的方法。这两个方法异常强大，他们允许切换函数执行的上下文环境（context）
      // 即 this 绑定的对象。  这里使用call 将 person1中的this 指向了 person2
      // 当我们使用 person2 作为参数来调用 person1.fullName 方法时, this 将指向 person2, 即便它是 person1 的方法
   </script>

   <script>
      "use strict"

      function fn() {
         return this
      }
      console.log(fn());
      //  在严格模式中 this 为 undefuned
   </script>
</body>

</html>